/**
 * 开始的时候模块化是一个个函数，这样可能会造成全局变量的污染，并且模块内部成员之间看不出关系
 */
function f1(){}
function f2(){}

/**
 * 采用对象的模式，对象里面封装了成员属性和方法，将对象作为一个个模块
 * 缺点：只要访问对象，就能访问对象内部的所有成员，外部代码可以改变模块内部状态
 */
let obj = {
    _count:0,
    f1:function(){},
    f2:function(){}
}
//通过对象.属性名访问

/**
 * 采用立即执行函数，封装内部变量，这样外部代码只能访问到我们想要暴露给他们的方法
 */
let module1 = (function(){
    let _count =0;
    function f1(){
        _count++;
        console.log(_count);
    }
    function f2(){
        _count--;
        console.log(_count);
    }
    return {
        f1,
        f2
    }
})();

module1.f1();

/**
 * 进行mixin注入，当我们发现某一个模块没有某种功能，可以采用立即执行函数进行注入
 */
let module2 = (function(mod){
    mod.f3 =function(){
        console.log("add a function");
    }
    return mod;
})(module1);

module2.f3();